package com.fw.system.admin.service.impl;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fw.common.IdXD;
import com.fw.constant.Constant;
import com.fw.constant.Constants;
import com.fw.core.redis.RedisCache;
import com.fw.enums.OrderState;
import com.fw.system.admin.domain.*;
import com.fw.system.admin.domain.vo.ScreenDataVo;
import com.fw.system.admin.domain.vo.ShopScreenDataVo;
import com.fw.system.admin.service.*;
import com.fw.utils.DateUtils;
import com.google.common.collect.Lists;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import com.fw.system.admin.mapper.FwShangjiaMapper;

import static com.fw.constant.Constants.ADMIN_LOOK;

/**
 * 商甲发行Service业务层处理
 *
 * @author yanwei
 * @date 2021-05-10
 */
@Service
public class FwShangjiaServiceImpl extends ServiceImpl<FwShangjiaMapper, FwShangjia> implements IFwShangjiaService {
    @Autowired
    private FwShangjiaMapper fwShangjiaMapper;

    @Autowired
    private IdXD idXD;

    @Autowired
    private IFwOrderService fwOrderService;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private IFwShopService fwShopService;

    @Autowired
    private IFwUcjoinService fwUcjoinService;

    @Autowired
    private IFwSpuService fwSpuService;

    @Autowired
    private IFwUsjoinService fwUsjoinService;

    @Autowired
    private  IFwUljoinService fwUljoinService;

    @Autowired
    private IFwOfflineService offlineService;

    @Autowired
    private IFwLockStorageService lockStorageService;

    @Autowired
    private IFwMoneysService moneysService;

    /**
     * 查询商甲发行
     *
     * @param id 商甲发行ID
     * @return 商甲发行
     */
    @Override
    public FwShangjia selectFwShangjiaById(String id) {
        return fwShangjiaMapper.selectFwShangjiaById(id);
    }

    /**
     * 查询商甲发行列表
     *
     * @param fwShangjia 商甲发行
     * @return 商甲发行
     */
    @Override
    public List<FwShangjia> selectFwShangjiaList(FwShangjia fwShangjia) {
        return fwShangjiaMapper.selectFwShangjiaList(fwShangjia);
    }

    /**
     * 新增商甲发行
     *
     * @param fwShangjia 商甲发行
     * @return 结果
     */
    @Override
    public int insertFwShangjia(FwShangjia fwShangjia) {
        fwShangjia.setCreateTime(DateUtils.getNowDate());
        fwShangjia.setId(idXD.nextId());
        return fwShangjiaMapper.insertFwShangjia(fwShangjia);
    }

    /**
     * 修改商甲发行
     *
     * @param fwShangjia 商甲发行
     * @return 结果
     */
    @Override
    public int updateFwShangjia(FwShangjia fwShangjia) {
        fwShangjia.setUpdateTime(DateUtils.getNowDate());
        return fwShangjiaMapper.updateFwShangjia(fwShangjia);
    }

    /**
     * 批量删除商甲发行
     *
     * @param ids 需要删除的商甲发行ID
     * @return 结果
     */
    @Override
    public int deleteFwShangjiaByIds(String[] ids) {
        return fwShangjiaMapper.deleteFwShangjiaByIds(ids);
    }

    /**
     * 删除商甲发行信息
     *
     * @param id 商甲发行ID
     * @return 结果
     */
    @Override
    public int deleteFwShangjiaById(String id) {
        return fwShangjiaMapper.deleteFwShangjiaById(id);
    }

    /** todo
     * 公众大屏数据:大屏商户
     */
    public void shopScreenData() {
        //获取所有的商户编号
        List<FwShop> shops = fwShopService.list();
        //判空
        if (shops.isEmpty()) {
            return;
        }

        //遍历所有的商户
        for (FwShop shop : shops) {
            String shopId = shop.getId();
            redisCache.deleteObject(Constants.SHOP_REDIS_KEY.concat(shopId));
            ArrayList<ShopScreenDataVo> shopScreenDataVos = Lists.newArrayList();
            //1 获取总订单量数据
            List<FwOrder>  orderList = fwOrderService.list(Wrappers.<FwOrder>lambdaQuery().eq(FwOrder::getShopId, shopId).eq(FwOrder::getRemoveFlag,"0"));
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("总订单量").val(orderList.size()).build());
            //2 获取待支付订单量
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("待支付订单量").val(orderList.parallelStream().filter(item ->OrderState.PENDING_PAYMENT.equals(item.getStatus()) ).count()).build());
            //4 获取待收货订单量
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("待收货订单量").val(orderList.parallelStream().filter(item ->OrderState.TO_BE_RECEIVED.equals(item.getStatus()) ).count()).build());
            //5 获取待评价订单量
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("待评价订单量").val(orderList.parallelStream().filter(item ->Integer.valueOf(0).equals(item.getIsAppraise())).count()).build());
            //6 获取退货退款订单量
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("退货退款订单量").val(orderList.parallelStream().filter(item ->OrderState.AFTER_SALE.equals(item.getStatus()) ).count()).build());
            //7 获取已收货订单量
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("已收货订单量").val(orderList.parallelStream().filter(item ->OrderState.RECEIVED.equals(item.getStatus()) ).count()).build());
            //8 获取竞猜订单量
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("竞猜订单量").val(orderList.parallelStream().filter(item -> Integer.valueOf(1).equals(item.getIsQuiz()) ).count()).build());

            //9 获取我的质押商甲:线上
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("质押商甲:线上").val(shop.getShangjia()).build());

            //10 获取我的质押商甲:线下
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("质押商甲:线上").val(shop.getOfflineShangjia()).build());

            //11 获取商家的商品收藏量
            List<FwSpu> spus = fwSpuService.list(Wrappers.<FwSpu>lambdaQuery().eq(FwSpu::getShopId, shopId));
            ArrayList<String> itemIds = new ArrayList<>();
            for (FwSpu spu : spus) {
                itemIds.add(spu.getId());
            }
            int itemCollectionCount = fwUcjoinService.list(Wrappers.<FwUcjoin>lambdaQuery().in(FwUcjoin::getItemId, itemIds)).size();
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("商品收藏量").val(itemCollectionCount).build());
            //12 获取商家的商铺收藏量
            int shopCollectionCount = fwUsjoinService.list(Wrappers.<FwUsjoin>lambdaQuery().eq(FwUsjoin::getShopId, shopId)).size();
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("商铺收藏量").val(shopCollectionCount).build());
            //13 获取商家线上订单累计收入金额
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("线上订单累计收入金额").val(orderList.parallelStream().map(item -> item.getTotalPrice()).reduce(BigDecimal::add).orElse(NumberUtil.add(0D))).build());

            //14 获取商家线下累计收入金额
            List<FwOffline> fwOfflines = offlineService.list(Wrappers.<FwOffline>lambdaQuery().eq(FwOffline::getShopId, shopId));
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("线下消费累计收入金额").val(fwOfflines.parallelStream().map(item -> item.getPrice()).reduce(BigDecimal::add).orElse(NumberUtil.add(0D))).build());
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日线上订单累计总量").val(orderList.parallelStream().filter(item -> item.getCreateTime().toLocalDate().equals(LocalDate.now())).count()).build());
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日线上订单累计收入金额").val(orderList.parallelStream().filter(item -> item.getCreateTime().toLocalDate().equals(LocalDate.now())).map(item -> item.getTotalPrice()).reduce(BigDecimal::add).orElse(NumberUtil.add(0D))).build());
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日线下消费累计收入金额").val(fwOfflines.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).map(item -> item.getPrice()).reduce(BigDecimal::add).orElse(NumberUtil.add(0D))).build());
            shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日竞猜订单累计金额").val(orderList.parallelStream().filter(item -> Integer.valueOf(1).equals(item.getIsQuiz()) && item.getCreateTime().toLocalDate().equals(LocalDate.now()) ).map(item -> item.getTotalPrice()).reduce(BigDecimal::add).orElse(NumberUtil.add(0D))).build());

            //存入redis
            redisCache.setCacheList(Constants.SHOP_REDIS_KEY.concat(shopId), shopScreenDataVos);
        }
    }

    /**
     * 公众大屏数据:系统管理员大屏
     */
    public void ScreenData() {
        redisCache.deleteObject(ADMIN_LOOK);

        ArrayList<ShopScreenDataVo> shopScreenDataVos = Lists.newArrayList();

        //1 获取总订单量数据
        List<FwOrder>  orderList = fwOrderService.list(Wrappers.<FwOrder>lambdaQuery().eq(FwOrder::getRemoveFlag,"0"));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("总订单量").val(orderList.size()).build());
        //2 获取待支付订单量
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("待支付订单量").val(orderList.parallelStream().filter(item ->OrderState.PENDING_PAYMENT.equals(item.getStatus()) ).count()).build());
        //4 获取待收货订单量
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("待收货订单量").val(orderList.parallelStream().filter(item ->OrderState.TO_BE_RECEIVED.equals(item.getStatus()) ).count()).build());
        //5 获取待评价订单量
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("待评价订单量").val(orderList.parallelStream().filter(item ->Integer.valueOf(0).equals(item.getIsAppraise())).count()).build());
        //6 获取退货退款订单量
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("退货退款订单量").val(orderList.parallelStream().filter(item ->OrderState.AFTER_SALE.equals(item.getStatus()) ).count()).build());
        //7 获取已收货订单量
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("已收货订单量").val(orderList.parallelStream().filter(item ->OrderState.RECEIVED.equals(item.getStatus()) ).count()).build());
        //8 获取竞猜订单量
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("竞猜订单量").val(orderList.parallelStream().filter(item -> Integer.valueOf(1).equals(item.getIsQuiz()) ).count()).build());

        //9 获取平台商甲产出记录

        List<FwMoneys> fwMoneys = moneysService.list();
        //10 获取全平台总消证
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("全平台总消证").val(fwMoneys.parallelStream().map(item -> item.getDisappear()).reduce(BigDecimal::add).get()).isClick(Boolean.TRUE).params("disappear").build());

        //11 获取全平台总积分
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("全平台总积分").val(fwMoneys.parallelStream().map(item -> item.getIntegral()).reduce(BigDecimal::add).get()).isClick(Boolean.TRUE).params("integral").build());

        //13 获取全平台总商甲
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("全平台总商甲").val(fwMoneys.parallelStream().map(item -> item.getShangJia()).reduce(BigDecimal::add).get()).build());

        //13 获取全平台技术商甲
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("全平台技术商甲").val(fwMoneys.parallelStream().map(item -> item.getTecShangjia()).reduce(BigDecimal::add).get()).build());

        //13 获取全平台管理商甲
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("全平台管理商甲").val(fwMoneys.parallelStream().map(item -> item.getManShangjia()).reduce(BigDecimal::add).get()).build());

        //12 获取平台商户累计收入top榜

        // 商甲锁仓池
        List<FwLockStorage> lockStorageList = lockStorageService.list();
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("商甲锁仓池总量:1000为一个单位").val(lockStorageList.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日新增商甲锁仓池总量:1000为一个单位").val(lockStorageList.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //13 获取平台商户总量
        List<FwShop> shopList = fwShopService.list();
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("平台商户总量").val(shopList.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日商户申请量").val(shopList.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());


        //14 获取vip总量
        List<FwUljoin> vipLists = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("VIP总量").val(vipLists.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日VIP新增量").val(vipLists.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //15 获取1星总量
        List<FwUljoin> oneStart = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.ONE_VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("一星总量").val(oneStart.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日一星新增量").val(oneStart.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //16 获取2星总量
        List<FwUljoin> rowStart = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.TWO_VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("二星总量").val(rowStart.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日二星新增量").val(rowStart.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //17 获取3星总量
        List<FwUljoin> threeStart = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.THREE_VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("三星总量").val(threeStart.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日三星新增量").val(threeStart.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //18 获取区县代理总量
        List<FwUljoin> areaLists = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.AREA_VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("区县代理总量").val(areaLists.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日区县代理新增量").val(areaLists.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //19 获取市级代理总量
        List<FwUljoin> cityLists = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.CITY_VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("市级代理总量").val(cityLists.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日市级代理新增量").val(cityLists.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());

        //20 获取省级代理总量
        List<FwUljoin> provinceLists = fwUljoinService.list(Wrappers.<FwUljoin>lambdaQuery().eq(FwUljoin::getIdentityId, Constant.Identity.PROVINCE_VIP_ID));
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("省级代理总量").val(provinceLists.size()).build());
        shopScreenDataVos.add(ShopScreenDataVo.builder().label("今日省级代理新增量").val(provinceLists.parallelStream().filter(item -> DateUtils.getDate().equals(DateUtil.format(item.getCreateTime(),DateUtils.YYYY_MM_DD))).count()).build());


        //存入redis
        redisCache.setCacheList(ADMIN_LOOK,shopScreenDataVos);
    }


}
